//  This file is part of Swordbible - http://www.swordwarrior.net
//  Copyright (C) 2003-2008 Manu Mital mital.manu@gmail.com

//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2, or (at your option)
//  any later version.

//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.

//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

// BibleCompare.cpp : implementation file
//

#include "stdafx.h"
#include "SwordBible.h"
#include "BibleCompare.h"
#include "BibleForm.h"
#include "BiblePage.h"


// CBibleCompare dialog

IMPLEMENT_DYNAMIC(CBibleCompare, CPropertyPage)

CBibleCompare::CBibleCompare()
	: CPropertyPage(CBibleCompare::IDD)
{
	

}

CBibleCompare::~CBibleCompare()
{
}

void CBibleCompare::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_COMPARE_RICHCTRL, m_rich);
}


BEGIN_MESSAGE_MAP(CBibleCompare, CPropertyPage)
	ON_WM_SIZE()
	ON_COMMAND(ID_COMPARE_COPY, OnCopy)
	ON_COMMAND(ID_COMPARE_SELECTALL, OnSelectAll)
	ON_COMMAND(ID_COMPARE_NEXT,OnNext)
	ON_COMMAND(ID_COMPARE_PREVIOUS,OnPrevious)
	ON_COMMAND(ID_COMPARE_PRINT,OnPrint)
	ON_COMMAND(ID_COMPARE_VERSIONS, OnShowVersions)
	ON_COMMAND(ID_COMPARE_ZOOM, OnZoom)
	ON_UPDATE_COMMAND_UI(ID_COMPARE_ZOOM, OnUpdateZoom)

	ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
   ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
  
	ON_MESSAGE(ID_BIBLEPAGE_COMMAND,OnMainFrameCommand)
	ON_NOTIFY(EN_MSGFILTER, IDC_COMPARE_RICHCTRL, &CBibleCompare::OnEnMsgfilterCompareRich)
END_MESSAGE_MAP()


// CBibleCompare message handlers

BOOL CBibleCompare::OnInitDialog()
{
	CPropertyPage::OnInitDialog();

	for(int i = 0; i < CSwordBibleDoc::numBiblesAvailable; i++)
	BibleActive[i] = TRUE;

	// Load the toolbar on the biblepage
	LoadToolbar();

	// Enable tool tips
	EnableToolTips();   // enable tool tips for view

	// to receive the mouse click events
	m_rich.SetEventMask(ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_SCROLLEVENTS);
	m_rich.SendMessage(EM_EXLIMITTEXT,0,-1);
	

	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

// this function loads the toolbar on the bible page
int CBibleCompare::LoadToolbar(void)
{
	
  if (!m_wndFormatBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD
       | WS_VISIBLE | CBRS_TOP |  CBRS_FLYBY | CBRS_TOOLTIPS) ||
       !m_wndFormatBar.LoadToolBar(IDR_TOOLBAR_COMPARE))
   {
      TRACE0("Failed to create toolbar\n");
      return -1;      // fail to create
   }

   // buttons size: 16
   // bitmaps:
   // enabled - IDB_TOOLBAR_NORMAL
   // hovered - IDB_TOOLBAR_HOT
   // disabled - IDB_TOOLBAR_DISABLED
   // transparent color RGB(255, 0, 255)
   m_wndFormatBar.LoadTCToolBar(24, IDB_TOOLBAR_COMPARE,IDB_TOOLBAR_COMPARE,
                              IDB_TOOLBAR_COMPARE, RGB(255,255,255));




	// Position the control bars using RepositionBars. 
	RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

	// Expand the size of the Toolbar window so all controls in it would fit
	
	CRect toolBarRect;
	CToolBarCtrl& formatBar = m_wndFormatBar.GetToolBarCtrl();
	formatBar.GetWindowRect(toolBarRect);
	ScreenToClient(toolBarRect);
	toolBarRect.left += 10  ;
	toolBarRect.right += 500  ;
	formatBar.MoveWindow(toolBarRect,TRUE);



	

	return 0;
}

void CBibleCompare::OnSize(UINT nType, int cx, int cy)
{
	CPropertyPage::OnSize(nType, cx, cy);

	// resize the rich edit control
    if(::IsWindow(m_rich.GetSafeHwnd()) == FALSE) return;
	m_rich.SetWindowPos(NULL,10,45,cx-20,cy-55,SWP_NOZORDER | SWP_NOACTIVATE);

}


// display the relevant text in the bible compare window
void CBibleCompare::ShowChapter(void)
{

	sword::VerseKey key = CSwordBibleDoc::key;
	
	// clear limits
	//   	MorphLimits.Clear();
	//	StrongLimits.Clear();
	//	Footnotes.RemoveAll();
	//	Xrefs.RemoveAll();
	//	XLimits.Clear();
			
	chapText = CBiblePage::font.GetHeaderRTF();

	chapText = chapText + "\\cf1\\b " + key.getText() + "\\b0\\par\\par ";
		
	int add = 0;

	   for(int i = 0; i < CSwordBibleDoc::numBiblesAvailable; i++)
			if(CSwordBibleDoc::pRTFBibleModule[i] && BibleActive[i] == TRUE)
		{
			add++; // another bible version added to compare

				CSwordBibleDoc::pRTFBibleModule[i]->SetKey(key);  // set key to current verse
				CString renderText = (CString) CSwordBibleDoc::pRTFBibleModule[i]->RenderText(); 
				renderText.Replace("\\par"," ");
			    renderText.Replace("\\cf6","\\cf9");

			
				// alternate between red and blue for displaying the bible version abbreviation
				// the text uses the color cf2 in the color table
				
				if(add%2 == 0) 
				chapText = chapText + "\\cf9 [" + CSwordBibleDoc::pRTFBibleModule[i]->Name() + "] \\cf2 " + renderText;

				else chapText = chapText + "\\cf10 [" + CSwordBibleDoc::pRTFBibleModule[i]->Name() + "] \\cf2 " + renderText;

		//	if(CSwordBibleDoc::fn_tags) AddFootNotes(renderText, key.Verse());
		//	if(CSwordBibleDoc::crossref_tags) AddXref(renderText, key.Verse());
	
			chapText += "\\par\\par ";	// each verse on a separate line
				
		}

		// Append the footnotes
	//	int count = Footnotes.GetCount();

	//	if(count)
	//	{
	//	chapText += "\\par\\cf5\\\ul Footnotes:\\ul0\\par\\sub ";	
	//	for(int i = 0; i < count ; i++) chapText = chapText +  pModule->RenderText(Footnotes.GetAt(i)) + "\\par ";
	//	}

        
	chapText += "}"; 

	// footnote tags are enclosed between href tags in bibles. Footnotes use color cf5 in the color table 
	// x reference tags are enclosed between href tags in bibles. cross references use color cf6 in the color table 
	chapText.Replace("<a href=\"\">*n",  "\\cf5\\b *n");
	chapText.Replace("<a href=\"\">*x",  "\\cf6\\b *x");
	chapText.Replace("</a>", "\\cf2\\b0 ");
	chapText.Replace("<a href=\"\">",  " ");
	 
	m_rich.SetRTF(chapText);
	

	ZoomText();


	//SetVerseLimits(VA);
//	CString version = pModule->Name();
//	if(CSwordBibleDoc::morph_tags && version == "KJV")   SetMorphLimits();
//	if(CSwordBibleDoc::lemma_tags && version == "KJV")   SetStrongLimits();
//	if(CSwordBibleDoc::crossref_tags) SetXLimits();


	
			
}




void CBibleCompare::OnShowVersions()
{
	RECT rc;
    m_wndFormatBar.GetToolBarCtrl().GetItemRect(0,&rc);
	ClientToScreen(&rc); // TrackPopupMenu uses screen coords

   CMenu menu;
   menu.CreatePopupMenu();
   CMenu* pPopup = NULL;
   pPopup = &menu;

   if(pPopup == NULL) return;
   int dwSelectionMade;  

 
   // fill in the strings for different bible versions
	for(int i = 0; i < CSwordBibleDoc::numBiblesAvailable; i++)
		if(CSwordBibleDoc::pRTFBibleModule[i] != NULL)
		{
			         pPopup->AppendMenu(MF_STRING,ID_BIBLEVERSION_NAMES + i, (CString) CSwordBibleDoc::pRTFBibleModule[i]->Description());
					 if(BibleActive[i]) pPopup->CheckMenuItem(ID_BIBLEVERSION_NAMES + i,MF_CHECKED); 

		}


         dwSelectionMade =  pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON|TPM_RETURNCMD, 
         rc.left, rc.bottom + 4, this);

	
		int selection = dwSelectionMade;
		int base = ID_BIBLEVERSION_NAMES;
		int activate = selection - base;


	if(activate >= 0 && activate < CSwordBibleDoc::numBiblesAvailable) 
	{
		BibleActive[activate] = !BibleActive[activate];
		ShowChapter();

	}
    pPopup->DestroyMenu(); 

}

void CBibleCompare::OnPrint()
{
		// only the active page should handle the message
		if(  !( ((CPropertySheet*) GetParent())->GetActivePage()   == this) )  
	  return;

	CBibleForm::pControl = (CRichEditCtrl *) GetDlgItem(IDC_COMPARE_RICHCTRL);
		AfxGetMainWnd()->SendMessageToDescendants(WM_PRINT_CONTROL, (WPARAM) 1 , 0);


}

void CBibleCompare::OnCopy()					// Copy selected text to clipboard
{
	// only the active page should handle the message
  if(  !( ((CPropertySheet*) GetParent())->GetActivePage()   == this) )  
	  return;

  m_rich.Copy();
	
}

void CBibleCompare::OnSelectAll()
{
		// only the active page should handle the message
  if(  !( ((CPropertySheet*) GetParent())->GetActivePage()   == this) )  
	  return;

  m_rich.SetSel(0,-1);


}

void CBibleCompare::OnZoom()
{
	// only the active page should handle the message
		if(  !( ((CPropertySheet*) GetParent())->GetActivePage()   == this) )  
	  return;

	CSwordBibleDoc::bibleZoom = !(CSwordBibleDoc::bibleZoom);
	ZoomText();

}

void CBibleCompare::OnUpdateZoom(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(CSwordBibleDoc::bibleZoom);

}

void CBibleCompare::ZoomText()
{
	if(CSwordBibleDoc::bibleZoom) m_rich.SendMessage(EM_SETZOOM, 5,4); //zoom by 1.25
	else m_rich.SendMessage(EM_SETZOOM, 0,0);  // turn off zooming
	
}




void CBibleCompare::OnPrevious()
{
	sword::VerseKey temp = CSwordBibleDoc::key;
	temp.Verse( temp.Verse() - 1);
	
	if(temp.Error()) 	 return;	

	CSwordBibleDoc::key = temp;
	ShowChapter();

	CWnd * pWnd = AfxGetMainWnd();

	if(CSwordBibleDoc::notesSynch)
	{
	CNotesPage::ActiveMainFrameCommand = "BibleSynch";
	pWnd->SendMessageToDescendants(ID_NOTES_COMMAND,0,0);
	}

	if(CSwordBibleDoc::bottomSynch)
	{
	CBottomPage::ActiveMainFrameCommand = "BibleSynch";
	pWnd->SendMessageToDescendants(ID_COMMENTARY_COMMAND,0,0);
	}
	

}

void CBibleCompare::OnNext()
{
	sword::VerseKey temp = CSwordBibleDoc::key;
	temp.Verse(temp.Verse() + 1);
	
	if(temp.Error()) return; 		
	
	CSwordBibleDoc::key = temp;
	ShowChapter();

	CWnd * pWnd = AfxGetMainWnd();

	if(CSwordBibleDoc::notesSynch)
	{
	CNotesPage::ActiveMainFrameCommand = "BibleSynch";
	pWnd->SendMessageToDescendants(ID_NOTES_COMMAND,0,0);
	}

	if(CSwordBibleDoc::bottomSynch)
	{
	CBottomPage::ActiveMainFrameCommand = "BibleSynch";
	pWnd->SendMessageToDescendants(ID_COMMENTARY_COMMAND,0,0);
	}
	

}

BOOL CBibleCompare::OnSetActive()
{
	ShowChapter();

	return CPropertyPage::OnSetActive();
}



LONG CBibleCompare::OnMainFrameCommand(UINT, LONG)
{
	// only the active page should handle the message
	if(  !( ((CPropertySheet*) GetParent())->GetActivePage()   == this) )  
	  return 0L;
  
	if(CBiblePage::ActiveMainFrameCommand == "ShowChapter") ShowChapter();
	
	 return 0L;
}


void CBibleCompare::OnEnMsgfilterCompareRich(NMHDR *pNMHDR, LRESULT *pResult)
{
	MSGFILTER *pMsgFilter = reinterpret_cast<MSGFILTER *>(pNMHDR);
	// TODO:  The control will not send this notification unless you override the
	// CPropertyPage::OnInitDialog() function to send the EM_SETEVENTMASK message
	// to the control with either the ENM_KEYEVENTS or ENM_MOUSEEVENTS flag 
	// ORed into the lParam mask.

	if (pMsgFilter->msg == WM_RBUTTONDOWN)   OnRightButtonDown();

	*pResult = 0;
}

void CBibleCompare::OnRightButtonDown()
{
	  CPoint point;                                            
     ::GetCursorPos(&point); //where is the mouse?
     CMenu menu; //lets display out context menu :) 
     DWORD dwSelectionMade;                                       
     VERIFY(menu.LoadMenu("IDR_MENU_COMPARE") );  
     CMenu *pmenuPopup = menu.GetSubMenu(0);
     ASSERT(pmenuPopup != NULL);   

	  if(CSwordBibleDoc::bibleZoom)	pmenuPopup->CheckMenuItem(ID_COMPARE_ZOOM,MF_CHECKED); 
	 
     dwSelectionMade = pmenuPopup->TrackPopupMenu( (TPM_LEFTALIGN|TPM_LEFTBUTTON|
                                                      TPM_RETURNCMD),
                                                    point.x, point.y, this); 

	

	
	switch (dwSelectionMade)
	{
	case ID_COMPARE_PRINT:			OnPrint(); break;
	case ID_COMPARE_COPY:			OnCopy(); break;
	case ID_COMPARE_SELECTALL:      OnSelectAll(); break;
	case ID_COMPARE_ZOOM:			OnZoom(); break; 
	case ID_COMPARE_PREVIOUS:		OnPrevious(); break;
	case ID_COMPARE_NEXT:			OnNext(); break;

	}

	
	pmenuPopup->DestroyMenu(); 

}

BOOL CBibleCompare::OnToolTipNotify(UINT id, NMHDR *pNMHDR,   LRESULT *pResult)
{
   // need to handle both ANSI and UNICODE versions of the message
   TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
   TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
   CString strTipText;
   UINT nID = pNMHDR->idFrom;
   if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
      pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
   {
      // idFrom is actually the HWND of the tool
      nID = ::GetDlgCtrlID((HWND)nID);
   }

   char buf[100];

   if (nID != 0) // will be zero on a separator
   {AfxLoadString(nID,buf,100 ); strTipText.Format("%s",buf);  }

   if (pNMHDR->code == TTN_NEEDTEXTA)
      lstrcpyn(pTTTA->szText, strTipText, sizeof(pTTTA->szText));
   else
      _mbstowcsz(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
   *pResult = 0;

   return TRUE;    // message was handled
}
